home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-19
/
iritsm3s.zip
/
X11GRAPH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-31
|
38KB
|
1,060 lines
/*****************************************************************************
* "Irit" - the 3d polygonal solid modeller. *
* *
* Written by: Gershon Elber Unix - X11 Ver 0.1, Mar. 1990 *
******************************************************************************
* General routines to handle the graphic calls. *
* currently supported devices: *
* Input: Keyboard, mouse. *
* Output: X11 device. *
*****************************************************************************/
#ifdef __hpux
typedef char *caddr_t; /* Awful kluge. Let me know of a better way. */
#endif /* __hpux */
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/Xresource.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include "graphgen.h"
#define POINT_SIZE 0.05 /* Size of + marker drawn. */
#define POINT_TITLE 0.02 /* Distance between point title and + marker. */
#define FONT_NAME "8x13"
#define PROGRAM_NAME "irit"
#define DEFAULT_TRANS_WIDTH 200
#define DEFAULT_TRANS_HEIGHT 500
#define DEFAULT_VIEW_WIDTH 400
#define DEFAULT_VIEW_HEIGHT 400
/* X global specific staff goes here: */
static Display *XDisplay;
static int XScreen;
static Window XRoot;
static Colormap XColorMap;
static GC XTransGraphContext;
static GC XViewGraphContext;
static Visual *XVisual;
static XImage *XImageBuffer;
static Pixmap XIcon;
static Cursor XCursor;
static XColor BlackColor;
static XFontStruct *XLoadedFont;
static XColor
*TransCursorColor = NULL,
*ViewCursorColor = NULL;
static unsigned long
TransBackGroundPixel,
TransBorderPixel,
TransTextPixel,
TransSubWinBackPixel,
TransSubWinBorderPixel,
ViewBackGroundPixel,
ViewBorderPixel,
ViewTextPixel;
static int
XFontYOffsetToCenter = 0,
AbortKeyPressed = FALSE,
TransHasSize = FALSE,
TransHasPos = FALSE,
TransPosX = 0,
TransPosY = 0,
ViewHasSize = FALSE,
ViewHasPos = FALSE,
ViewPosX = 0,
ViewPosY = 0,
CurrentXPosition = 0,
CurrentYPosition = 0,
PopTransWndwAlways = TRUE,
LclFullTransMode = TRUE,
InGraphicMode = FALSE;
static unsigned int
TransBorderWidth = 1,
TransSubWinBorderWidth = 1,
TransWidth = DEFAULT_TRANS_WIDTH,
TransHeight = DEFAULT_TRANS_HEIGHT,
ViewBorderWidth = 1,
ViewWidth = DEFAULT_VIEW_WIDTH,
ViewHeight = DEFAULT_VIEW_HEIGHT;
/* X Colors to be used for viewed object (see also xgraphic.h): */
int XViewColorDefs[MAX_COLOR + 1][3] =
{
{ 0, 0, 0 }, /* 0. BLACK */
{ 0, 0, 43350 }, /* 1. BLUE */
{ 0, 43350, 0 }, /* 2. GREEN */
{ 0, 43350, 43350 }, /* 3. CYAN */
{ 43350, 0, 0 }, /* 4. RED */
{ 43350, 0, 43350 }, /* 5. MAGENTA */
{ 43350, 43350, 0 }, /* 6. BROWN */
{ 43350, 43350, 43350 }, /* 7. LIGHTGREY */
{ 21675, 21675, 21675 }, /* 8. DARKGRAY */
{ 21675, 21675, 65535 }, /* 9. LIGHTBLUE */
{ 21675, 65535, 21675 }, /* 10. LIGHTGREEN */
{ 21675, 65535, 65535 }, /* 11. LIGHTCYAN */
{ 65535, 21675, 21675 }, /* 12. LIGHTRED */
{ 65535, 21675, 65535 }, /* 13. LIGHTMAGENTA */
{ 65535, 65535, 21675 }, /* 14. YELLOW */
{ 65535, 65535, 65535 } /* 15. WHITE */
};
XColor XViewColors[MAX_COLOR + 1];
/* X Viewing window staff goes here: */
static Window ViewWndw;
/* X transformation window staff goes here: */
static Window TransformWndw;
static Window ObjScrTglWndw;
static Window PersOrthoTglWndw, PersOrthoZWndw;
static Window RotateXWndw, RotateYWndw, RotateZWndw;
static Window TranslateXWndw, TranslateYWndw, TranslateZWndw;
static Window ScaleWndw;
static Window DepthCueWndw;
static Window SaveGIFWndw;
static Window SavePSWndw;
static Window SaveMatrixWndw;
static Window ResetMatrixWndw;
static Window QuitWndw;
/* Viewing state variables: */
static int
ObjectSpaceState = FALSE,
PerspectiveState = FALSE,
DepthCueState = FALSE,
SubWindowWidthState2 = 1,
SubWindowHeightState2 = 1;
static int GGMapX(RealType x);
static int GGMapY(RealType y);
static void ReadXDefaults(void);
static char *ReadOneXDefault(char *Entry);
static void SetTransformWindow(int argc, char **argv);
static void RedrawTransformWindow(void);
static Window SetTransformSubWindow(int SubTransPosX, int SubTransPosY,
unsigned int SubTransWidth, unsigned int SubTransHeight);
static void RedrawTransformSubWindow(Window Win,
int SubTransPosX, int SubTransPosY,
unsigned int SubTransWidth, unsigned int SubTransHeight,
int DrawMiddleVertLine, char *DrawString);
static void SetViewWindow(int argc, char **argv);
static void DrawText(Window Win, char *Str, int PosX, int PosY,
unsigned long Color);
/****************************************************************************
* Routine to map real -1..1 normalized coordinates to screen X size. *
****************************************************************************/
static int GGMapX(RealType x)
{
return ((int) ((x + 1.0) * ViewWidth)) / 2;
}
/****************************************************************************
* Routine to map real -1..1 normalized coordinates to screen Y size. *
****************************************************************************/
static int GGMapY(RealType y)
{
return ((int) ((1.0 - y) * ViewHeight)) / 2;
}
/****************************************************************************
* Routine to move to a normalized point between -1..1 on both axes : *
****************************************************************************/
void GGMyMove(RealType x, RealType y)
{
CurrentXPosition = GGMapX(x);
CurrentYPosition = GGMapY(y);
}
/****************************************************************************
* Routine to draw to a normalized point between -1..1 on both axes : *
****************************************************************************/
void GGMyDraw(RealType x, RealType y)
{
int NewX, NewY;
XDrawLine(XDisplay, ViewWndw, XViewGraphContext,
CurrentXPosition, CurrentYPosition,
NewX = GGMapX(x), NewY = GGMapY(y));
CurrentXPosition = NewX;
CurrentYPosition = NewY;
}
/****************************************************************************
* Routine to set line style. *
****************************************************************************/
void GGMySetLineStyle(int Style)
{
switch (Style) {
case SOLID_LINE:
XSetLineAttributes(XDisplay, XViewGraphContext,
0, LineSolid, CapRound, JoinRound);
break;
case DOTTED_LINE:
XSetLineAttributes(XDisplay, XViewGraphContext,
0, LineOnOffDash, CapRound, JoinRound);
break;
}
}
/****************************************************************************
* Routine to draw to a normelized point between -1..1 on both axes : *
****************************************************************************/
void GGMySetColor(int color)
{
XGCValues values;
if (color > MAX_COLOR) color = WHITE;
values.foreground = XViewColors[color].pixel;
XChangeGC(XDisplay, XViewGraphContext, GCForeground, &values);
}
/****************************************************************************
* Routine to reset all the system to starting condition : *
****************************************************************************/
void GGInitGraph(int argc, char **argv, int FullTransMode, int TransAlways)
{
int i;
XGCValues values;
LclFullTransMode = FullTransMode;
PopTransWndwAlways = TransAlways;
/* Lets see if we can get access to the X server before we even start: */
if ((XDisplay = (Display *) XOpenDisplay(NULL)) == NULL) {
fprintf(stderr, "Failed to access X server, abored.\n");
MyExit(-1);
}
if ((XLoadedFont = XLoadQueryFont(XDisplay, FONT_NAME)) == NULL) {
fprintf(stderr, "Failed to load required X font \"%s\", aborted.\n",
FONT_NAME);
MyExit(-1);
}
XFontYOffsetToCenter = (XLoadedFont -> ascent - XLoadedFont -> descent + 1)
/ 2;
XScreen = DefaultScreen(XDisplay);
XRoot = RootWindow(XDisplay, XScreen);
XColorMap = DefaultColormap(XDisplay, XScreen);
XVisual = DefaultVisual(XDisplay, XScreen);
values.foreground = WhitePixel(XDisplay, XScreen);
values.background = BlackPixel(XDisplay, XScreen);
values.font = XLoadedFont -> fid;
XTransGraphContext = XCreateGC(XDisplay, XRoot,
GCForeground | GCBackground | GCFont, &values);
XViewGraphContext = XCreateGC(XDisplay, XRoot,
GCForeground | GCBackground, &values);
if (XDisplay->db == NULL)
XGetDefault(XDisplay, "", "");
ReadXDefaults();
for (i = 0; i <= MAX_COLOR; i++) {
XViewColors[i].red = XViewColorDefs[i][0];
XViewColors[i].green = XViewColorDefs[i][1];
XViewColors[i].blue = XViewColorDefs[i][2];
/* If fails to allocate the color - take WHITE instead. */
if (!XAllocColor(XDisplay, XColorMap, &XViewColors[i]))
XViewColors[i].pixel = WhitePixel(XDisplay, XScreen);
}
SetTransformWindow(argc, argv);
SetViewWindow(argc, argv);
GGGraphicFlush();
InGraphicMode = TRUE;
}
/****************************************************************************
* Routine to close and shutdown graphic mode : *
****************************************************************************/
void GGCloseGraph(void)
{
if (!InGraphicMode) return;
XFreeGC(XDisplay, XViewGraphContext);
XFreeGC(XDisplay, XTransGraphContext);
XUnloadFont(XDisplay, XLoadedFont -> fid);
XCloseDisplay(XDisplay);
InGraphicMode = FALSE;
}
/*****************************************************************************
* Routine to print an message on the given location: *
*****************************************************************************/
void GGPutMsgXY(char *s, RealType x, RealType y)
{
int Len = strlen(s),
Width = XTextWidth(XLoadedFont, s, Len),
PosX = GGMapX(x),
PosY = GGMapY(y);
XGCValues values;
XDrawString(XDisplay, ViewWndw, XViewGraphContext, PosX - Width / 2,
PosY + XFontYOffsetToCenter, s, Len);
}
/*****************************************************************************
* Routine to clear the vewing area. *
*****************************************************************************/
void GGClearViewArea(void)
{
XClearWindow(XDisplay, ViewWndw);
}
/*****************************************************************************
* Routine to make some sound with given Frequency, Time milliseconds: *
*****************************************************************************/
void GGTone(int Frequency, int Duration)
{
if (GlblDoGraphics)
XBell(XDisplay, 0);
}
/*****************************************************************************
* Read one default from X resource data base. *
*****************************************************************************/
static char *ReadOneXDefault(char *Entry)
{
XrmString Type;
XrmValue Result;
char Line[LINE_LEN_LONG];
sprintf(Line, "%s.%s", PROGRAM_NAME, Entry);
if ( XrmGetResource(XDisplay->db, Line, "Program.Name", &Type, &Result ) )
return Result.addr;
else
return NULL;
}
/*****************************************************************************
* Read Defaults from X data base. *
*****************************************************************************/
static void ReadXDefaults(void)
{
int i;
XColor Color;
char *TransBackGroundColor = ReadOneXDefault("Trans.BackGround"),
*TransBorderColor = ReadOneXDefault("Trans*BorderColor"),
*TransBorderWidthStr = ReadOneXDefault("Trans*BorderWidth"),
*TransTextColor = ReadOneXDefault("Trans.TextColor"),
*TransSubWinBackColor = ReadOneXDefault("Trans.SubWin.BackGround"),
*TransSubWinBorderColor = ReadOneXDefault("Trans.SubWin.BorderColor"),
*TransSubWinBorderWidthStr = ReadOneXDefault("Trans.SubWin.BorderWidth"),
*TransGeometry = ReadOneXDefault("Trans.Geometry"),
*TransCursorColorStr = ReadOneXDefault("Trans.CursorColor"),
*ViewBackGroundColor = ReadOneXDefault("View.BackGround"),
*ViewTextColor = ReadOneXDefault("View.TextColor"),
*ViewBorderColor = ReadOneXDefault("View.BorderColor"),
*ViewBorderWidthStr = ReadOneXDefault("View.BorderWidth"),
*ViewGeometry = ReadOneXDefault("View.Geometry"),
*ViewCursorColorStr = ReadOneXDefault("View.CursorColor");
if (XParseColor(XDisplay, XColorMap, "Black", &BlackColor))
XAllocColor(XDisplay, XColorMap, &BlackColor);
if (TransBackGroundColor != NULL &&
XParseColor(XDisplay, XColorMap, TransBackGroundColor, &Color) &&
XAllocColor(XDisplay, XColorMap, &Color))
TransBackGroundPixel = Color.pixel;
else
TransBackGroundPixel = BlackPixel(XDisplay, XScreen);
if (TransBorderColor != NULL &&
XParseColor(XDisplay, XColorMap, TransBorderColor, &Color) &&
XAllocColor(XDisplay, XColorMap, &Color))
TransBorderPixel = Color.pixel;
else
TransBorderPixel = WhitePixel(XDisplay, XScreen);
if (TransBorderWidthStr)
TransBorderWidth = atoi(TransBorderWidthStr);
else
TransBorderWidth = 1;
if (TransTextColor != NULL &&
XParseColor(XDisplay, XColorMap, TransTextColor, &Color) &&
XAllocColor(XDisplay, XColorMap, &Color))
TransTextPixel = Color.pixel;
else
TransTextPixel = WhitePixel(XDisplay, XScreen);
if (TransSubWinBackColor != NULL &&
XParseColor(XDisplay, XColorMap, TransSubWinBackColor, &Color) &&
XAllocColor(XDisplay, XColorMap, &Color))
TransSubWinBackPixel = Color.pixel;
else
TransSubWinBackPixel = BlackPixel(XDisplay, XScreen);
if (TransSubWinBorderColor != NULL &&
XParseColor(XDisplay, XColorMap, TransSubWinBorderColor, &Color) &&
XAllocColor(XDisplay, XColorMap, &Color))
TransSubWinBorderPixel = Color.pixel;
else
TransSubWinBorderPixel = WhitePixel(XDisplay, XScreen);
if (TransSubWinBorderWidthStr)
TransSubWinBorderWidth = atoi(TransSubWinBorderWidthStr);
else
TransSubWinBorderWidth = 1;
if (TransGeometry) {
i = XParseGeometry(TransGeometry, &TransPosX, &TransPosY,
&TransWidth, &TransHeight);
TransHasPos = i & XValue && i & YValue;
TransHasSize = i & WidthValue && i & HeightValue;
}
else
TransHasSize = TransHasPos = FALSE;
if (TransCursorColorStr != NULL &&
XParseColor(XDisplay, XColorMap, TransCursorColorStr, &Color) &&
XAllocColor(XDisplay, XColorMap, &Color)) {
TransCursorColor = (XColor *) malloc(sizeof(XColor));
*TransCursorColor = Color;
}
else
TransCursorColor = NULL;
if (ViewBackGroundColor &&
XParseColor(XDisplay, XColorMap, ViewBackGroundColor, &Color) &&
XAllocColor(XDisplay, XColorMap, &Color))
ViewBackGroundPixel = Color.pixel;
else
ViewBackGroundPixel = BlackPixel(XDisplay, XScreen);
if (ViewBorderColor &&
XParseColor(XDisplay, XColorMap, ViewBorderColor, &Color) &&
XAllocColor(XDisplay, XColorMap, &Color))
ViewBorderPixel = Color.pixel;
else
ViewBorderPixel = WhitePixel(XDisplay, XScreen);
if (ViewTextColor != NULL &&
XParseColor(XDisplay, XColorMap, ViewTextColor, &Color) &&
XAllocColor(XDisplay, XColorMap, &Color))
ViewTextPixel = Color.pixel;
else
ViewTextPixel = WhitePixel(XDisplay, XScreen);
if (ViewBorderWidthStr)
ViewBorderWidth = atoi(ViewBorderWidthStr);
else
ViewBorderWidth = 1;
if (ViewGeometry) {
i = XParseGeometry(ViewGeometry, &ViewPosX, &ViewPosY,
&ViewWidth, &ViewHeight);
ViewHasPos = i & XValue && i & YValue;
ViewHasSize = i & WidthValue && i & HeightValue;
}
else ViewHasSize = ViewHasPos = FALSE;
if (ViewCursorColorStr != NULL &&
XParseColor(XDisplay, XColorMap, ViewCursorColorStr, &Color) &&
XAllocColor(XDisplay, XColorMap, &Color)) {
ViewCursorColor = (XColor *) malloc(sizeof(XColor));
*ViewCursorColor = Color;
}
else
ViewCursorColor = NULL;
}
/*****************************************************************************
* Set up and draw a transformation window. *
*****************************************************************************/
static void SetTransformWindow(int argc, char **argv)
{
int SubTransPosX, SubTransPosY, SubTransWidth, SubTransHeight;
long ValueMask;
XSizeHints Hints;
XSetWindowAttributes SetWinAttr;
SetWinAttr.background_pixel = TransBackGroundPixel;
SetWinAttr.border_pixel = TransBorderPixel;
ValueMask = CWBackPixel | CWBorderPixel;
Hints.flags = PMinSize | PMaxSize;
Hints.x = Hints.y = 1;
Hints.min_width = 100;
Hints.max_width = 1000;
Hints.min_height = 200;
Hints.max_height = 1000;
if (TransHasSize) {
Hints.flags |= PSize;
if (TransWidth < Hints.min_width) TransWidth = Hints.min_width;
if (TransWidth > Hints.max_width) TransWidth = Hints.max_width;
if (TransHeight < Hints.min_height) TransHeight = Hints.min_height;
if (TransHeight > Hints.max_height) TransHeight = Hints.max_height;
Hints.width = TransWidth;
Hints.height = TransHeight;
}
else {
Hints.flags |= PSize;
Hints.width = TransWidth = DEFAULT_TRANS_WIDTH;
Hints.height = TransHeight = DEFAULT_TRANS_HEIGHT;
}
if (TransHasPos) {
Hints.flags |= USPosition;
Hints.x = TransPosX;
Hints.y = TransPosY;
}
TransformWndw = XCreateWindow(XDisplay, XRoot,
TransPosX, TransPosY,
TransWidth, TransHeight,
1, 0, CopyFromParent, CopyFromParent,
ValueMask, &SetWinAttr);
XSetStandardProperties(XDisplay, TransformWndw,
PROGRAM_NAME, PROGRAM_NAME, None,
argv, argc,
&Hints);
/* Set our own cursor: */
XCursor = XCreateFontCursor(XDisplay, XC_hand1);
XDefineCursor(XDisplay, TransformWndw, XCursor);
if (TransCursorColor != NULL)
XRecolorCursor(XDisplay, XCursor, TransCursorColor, &BlackColor);
/* Now lets create the sub windows inside. Note we do not place them yet. */
SubTransPosX = 0;
SubTransPosY = TransHeight;
SubTransWidth = TransWidth - SubTransPosX * 2;
SubTransHeight = TransHeight / 25;
/* OBJECT/SCREEN space toggle: */
ObjScrTglWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
/* PERSPECTIVE/ORTHOGRPHIC toggle: */
PersOrthoTglWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
PersOrthoZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
/* ROTATE: */
RotateXWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
RotateYWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
RotateZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
/* TRANSLATE: */
TranslateXWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
TranslateYWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
TranslateZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
/* SCALE: */
ScaleWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
/* DEPTH CUE: */
DepthCueWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
if (LclFullTransMode) {
/* SAVE GIF: */
SaveGIFWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
/* SAVE PS: */
SavePSWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
/* SAVE MATRIX: */
SaveMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
}
/* RESET MATRIX: */
ResetMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
/* QUIT: */
QuitWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
XSelectInput(XDisplay, TransformWndw, ExposureMask);
ObjectSpaceState = GlblTransformMode == TRANS_OBJECT;
PerspectiveState = GlblViewMode == VIEW_PERSPECTIVE;
DepthCueState = GlblDepthCue;
}
/*****************************************************************************
* Redraw a transformation window (after exposure or resize events). *
*****************************************************************************/
static void RedrawTransformWindow(void)
{
int SubTransPosX, SubTransPosY,
SizeChanged = FALSE;
unsigned long SubTransWidth, SubTransHeight;
long ValueMask;
XSizeHints Hints;
XWindowAttributes TransWindowAttr;
XSetWindowAttributes SetWinAttr;
XClearWindow(XDisplay, TransformWndw);
/* Get the window attributes, and see if it is the same size or not. */
XGetWindowAttributes(XDisplay, TransformWndw, &TransWindowAttr);
if (TransWindowAttr.width != TransWidth ||
TransWindowAttr.height != TransHeight)
{
SizeChanged = TRUE;
TransWidth = TransWindowAttr.width;
TransHeight = TransWindowAttr.height;
}
/* Now lets update the sub windows inside: */
SubTransPosX = MIN(TransWidth / 10, 20);
SubTransPosY = TransHeight / (LclFullTransMode ? 30 : 25);
SubTransWidth = TransWidth - SubTransPosX * 2;
SubTransHeight = TransHeight / (LclFullTransMode ? 30 : 25);
/* OBJECT/SCREEN space toggle: */
RedrawTransformSubWindow(ObjScrTglWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, FALSE,
GlblTransformMode == TRANS_OBJECT ?
"Object" : "Screen");
SubTransPosY += SubTransHeight * 2;
/* PERSPECTIVE/ORTHOGRAPHIC toggle: */
RedrawTransformSubWindow(PersOrthoTglWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, FALSE,
GlblViewMode == VIEW_ORTHOGRAPHIC ?
"Orthographic" : "Perspective");
SubTransPosY += SubTransHeight;
RedrawTransformSubWindow(PersOrthoZWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, TRUE, NULL);
SubTransPosY += SubTransHeight;
DrawText(TransformWndw, "Z", SubTransPosX / 2,
SubTransPosY - SubTransHeight / 4, TransTextPixel);
SubTransPosY += SubTransHeight;
/* ROTATE: */
DrawText(TransformWndw, "Rotate", TransWidth / 2, SubTransPosY,
TransTextPixel);
SubTransPosY += SubTransHeight / 2;
RedrawTransformSubWindow(RotateXWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, TRUE, NULL);
SubTransPosY += SubTransHeight;
DrawText(TransformWndw, "X", SubTransPosX / 2,
SubTransPosY - SubTransHeight / 4, TransTextPixel);
RedrawTransformSubWindow(RotateYWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, TRUE, NULL);
SubTransPosY += SubTransHeight;
DrawText(TransformWndw, "Y", SubTransPosX / 2,
SubTransPosY - SubTransHeight / 4, TransTextPixel);
RedrawTransformSubWindow(RotateZWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, TRUE, NULL);
SubTransPosY += SubTransHeight;
DrawText(TransformWndw, "Z", SubTransPosX / 2,
SubTransPosY - SubTransHeight / 4, TransTextPixel);
/* TRANSLATE: */
SubTransPosY += SubTransHeight;
DrawText(TransformWndw, "Translate", TransWidth / 2, SubTransPosY,
TransTextPixel);
SubTransPosY += SubTransHeight / 2;
RedrawTransformSubWindow(TranslateXWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, TRUE, NULL);
SubTransPosY += SubTransHeight;
DrawText(TransformWndw, "X", SubTransPosX / 2,
SubTransPosY - SubTransHeight / 4, TransTextPixel);
RedrawTransformSubWindow(TranslateYWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, TRUE, NULL);
SubTransPosY += SubTransHeight;
DrawText(TransformWndw, "Y", SubTransPosX / 2,
SubTransPosY - SubTransHeight / 4, TransTextPixel);
RedrawTransformSubWindow(TranslateZWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, TRUE, NULL);
SubTransPosY += SubTransHeight;
DrawText(TransformWndw, "Z", SubTransPosX / 2,
SubTransPosY - SubTransHeight / 4, TransTextPixel);
/* SCALE: */
SubTransPosY += SubTransHeight;
DrawText(TransformWndw, "Scale", TransWidth / 2, SubTransPosY,
TransTextPixel);
SubTransPosY += SubTransHeight / 2;
RedrawTransformSubWindow(ScaleWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, TRUE, NULL);
/* DEPTH CUE: */
SubTransPosY += SubTransHeight * 2;
RedrawTransformSubWindow(DepthCueWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, FALSE,
GlblDepthCue ? "Depth Cue" : "No Depth Cue");
if (LclFullTransMode) {
/* SAVE GIF: */
SubTransPosY += SubTransHeight * 2;
RedrawTransformSubWindow(SaveGIFWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, FALSE,
"Save GIF");
/* SAVE PS: */
SubTransPosY += SubTransHeight * 2;
RedrawTransformSubWindow(SavePSWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, FALSE,
"Save PS");
/* SAVE MATRIX: */
SubTransPosY += SubTransHeight * 2;
RedrawTransformSubWindow(SaveMatrixWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, FALSE,
"Save Matrix");
}
/* RESET MATRIX: */
SubTransPosY += SubTransHeight * 2;
RedrawTransformSubWindow(ResetMatrixWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, FALSE,
"Reset Matrix");
/* QUIT: */
SubTransPosY += SubTransHeight * 3;
RedrawTransformSubWindow(QuitWndw, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight, FALSE, "Quit" );
/* Save half of the window width so we can refer to the zero point on X */
/* axes, which is the vertical line in the middle of the window: */
SubWindowWidthState2 = SubTransWidth / 2;
SubWindowHeightState2 = SubTransHeight / 2;
GGGraphicFlush();
}
/*****************************************************************************
* Set up a transformation sub window. *
*****************************************************************************/
static Window SetTransformSubWindow(int SubTransPosX, int SubTransPosY,
unsigned int SubTransWidth, unsigned int SubTransHeight)
{
long ValueMask;
XSetWindowAttributes SetWinAttr;
Window Win;
SetWinAttr.background_pixel = TransSubWinBackPixel;
SetWinAttr.border_pixel = TransSubWinBorderPixel;
SetWinAttr.bit_gravity = SetWinAttr.win_gravity = CenterGravity;
ValueMask = CWBackPixel | CWBorderPixel | CWBitGravity | CWWinGravity;
Win = XCreateWindow(XDisplay, TransformWndw,
SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight,
1, 0, CopyFromParent, CopyFromParent,
ValueMask, &SetWinAttr);
XSelectInput(XDisplay, Win, ButtonPressMask | Button1MotionMask);
XMapWindow(XDisplay, Win);
return Win;
}
/*****************************************************************************
* Redraw a transformation sub window. *
*****************************************************************************/
static void RedrawTransformSubWindow(Window Win,
int SubTransPosX, int SubTransPosY,
unsigned int SubTransWidth, unsigned int SubTransHeight,
int DrawMiddleVertLine, char *DrawString)
{
XGCValues values;
XMoveResizeWindow(XDisplay, Win, SubTransPosX, SubTransPosY,
SubTransWidth, SubTransHeight);
if (DrawMiddleVertLine) {
values.foreground = TransSubWinBorderPixel;
XChangeGC(XDisplay, XTransGraphContext, GCForeground, &values);
XDrawLine(XDisplay, Win, XTransGraphContext,
SubTransWidth / 2, 0, SubTransWidth / 2, SubTransHeight);
}
if (DrawString != NULL) {
DrawText(Win, DrawString, SubTransWidth / 2, SubTransHeight / 2,
TransTextPixel);
}
}
/*****************************************************************************
* Set up a view window. *
*****************************************************************************/
static void SetViewWindow(int argc, char **argv)
{
long ValueMask;
XSizeHints Hints;
XSetWindowAttributes SetWinAttr;
SetWinAttr.background_pixel = ViewBackGroundPixel;
SetWinAttr.border_pixel = ViewBorderPixel;
ValueMask = CWBackPixel | CWBorderPixel;
Hints.flags = PMinSize | PMaxSize;
Hints.x = Hints.y = 1;
Hints.min_width = 50;
Hints.max_width = 1000;
Hints.min_height = 50;
Hints.max_height = 1000;
if (ViewHasSize) {
Hints.flags |= PSize;
if (ViewWidth < Hints.min_width) ViewWidth = Hints.min_width;
if (ViewWidth > Hints.max_width) ViewWidth = Hints.max_width;
if (ViewHeight < Hints.min_height) ViewHeight = Hints.min_height;
if (ViewHeight > Hints.max_height) ViewHeight = Hints.max_height;
Hints.width = ViewWidth;
Hints.height = ViewHeight;
}
else {
Hints.flags |= PSize;
Hints.width = ViewWidth = DEFAULT_VIEW_WIDTH;
Hints.height = ViewHeight = DEFAULT_VIEW_HEIGHT;
}
if (ViewHasPos) {
Hints.flags |= USPosition;
Hints.x = ViewPosX;
Hints.y = ViewPosY;
}
ViewWndw = XCreateWindow(XDisplay, XRoot,
ViewPosX, ViewPosY,
ViewWidth, ViewHeight,
1, 0, CopyFromParent, CopyFromParent,
ValueMask, &SetWinAttr);
XSetStandardProperties(XDisplay, ViewWndw,
PROGRAM_NAME, PROGRAM_NAME, None,
argv, argc,
&Hints);
/* Set our own cursor: */
XCursor = XCreateFontCursor(XDisplay, XC_iron_cross);
XDefineCursor(XDisplay, ViewWndw, XCursor);
if (ViewCursorColor != NULL)
XRecolorCursor(XDisplay, XCursor, ViewCursorColor, &BlackColor);
XSelectInput(XDisplay, ViewWndw, ExposureMask | ButtonPressMask);
XMapWindow(XDisplay, ViewWndw);
}
/*****************************************************************************
* Return View window ID and the address of the display it is in. *
*****************************************************************************/
long GGGetViewWindowID(long *XDisplayAddr, long *XColorMapID)
{
*XDisplayAddr = (long) XDisplay;
*XColorMapID = (long) XColorMap;
return (long) ViewWndw;
}
/******************************************************************************
* Returns status of abort key if pressed, and reset it. *
******************************************************************************/
int GGIsAbortKeyPressed(void)
{
int RetVal = AbortKeyPressed;
AbortKeyPressed = FALSE;
return RetVal;
}
/******************************************************************************
* Flush output of graphic command. *
******************************************************************************/
void GGGraphicFlush(void)
{
XFlush(XDisplay);
}
/******************************************************************************
* Handle X events *
******************************************************************************/
GraphicEventType GGGetGraphicEvent(RealType *ChangeFactor)
{
static int LastX;
int Dx;
XEvent Event;
XWindowAttributes WinAttr;
XMapWindow(XDisplay, TransformWndw);
while (TRUE) {
XNextEvent(XDisplay, &Event);
switch (Event.type) {
case Expose:
/* Get rid of all Expose events in the queue. */
while (XCheckWindowEvent(XDisplay, Event.xbutton.window,
ExposureMask, &Event));
if (Event.xbutton.window == TransformWndw)
RedrawTransformWindow();
else if (Event.xbutton.window == ViewWndw) {
XGetWindowAttributes(XDisplay, ViewWndw, &WinAttr);
ViewWidth = WinAttr.width;
ViewHeight = WinAttr.height;
UpdateInteractHandleInput();
}
break;
case ButtonPress:
LastX = Event.xbutton.x;
*ChangeFactor = ((RealType) (LastX - SubWindowWidthState2)) /
SubWindowWidthState2;
if (Event.xbutton.button == 3) {
AbortKeyPressed = TRUE;
break;
}
if (Event.xbutton.window == ObjScrTglWndw) {
XClearWindow(XDisplay, ObjScrTglWndw);
GlblTransformMode = GlblTransformMode == TRANS_OBJECT ?
TRANS_SCREEN :
TRANS_OBJECT;
DrawText(ObjScrTglWndw,
GlblTransformMode == TRANS_OBJECT ? "Object" :
"Screen",
SubWindowWidthState2, SubWindowHeightState2,
TransTextPixel);
return EVENT_SCR_OBJ_TGL;
}
else if (Event.xbutton.window == PersOrthoTglWndw) {
XClearWindow(XDisplay, PersOrthoTglWndw);
GlblViewMode = GlblViewMode == VIEW_PERSPECTIVE ?
VIEW_ORTHOGRAPHIC :
VIEW_PERSPECTIVE;
DrawText(PersOrthoTglWndw,
GlblViewMode == VIEW_PERSPECTIVE ? "Perspective" :
"Orthographic",
SubWindowWidthState2, SubWindowHeightState2,
TransTextPixel);
return EVENT_PERS_ORTHO_TGL;
}
else if (Event.xbutton.window == PersOrthoZWndw) {
return EVENT_PERS_ORTHO_Z;
}
else if (Event.xbutton.window == RotateXWndw) {
return EVENT_ROTATE_X;
}
else if (Event.xbutton.window == RotateYWndw) {
return EVENT_ROTATE_Y;
}
else if (Event.xbutton.window == RotateZWndw) {
return EVENT_ROTATE_Z;
}
else if (Event.xbutton.window == TranslateXWndw) {
return EVENT_TRANSLATE_X;
}
else if (Event.xbutton.window == TranslateYWndw) {
return EVENT_TRANSLATE_Y;
}
else if (Event.xbutton.window == TranslateZWndw) {
return EVENT_TRANSLATE_Z;
}
else if (Event.xbutton.window == ScaleWndw) {
return EVENT_SCALE;
}
else if (Event.xbutton.window == DepthCueWndw) {
XClearWindow(XDisplay, DepthCueWndw);
GlblDepthCue = !GlblDepthCue;
DrawText(DepthCueWndw,
GlblDepthCue ? "Depth Cue" : "No Depth Cue",
SubWindowWidthState2, SubWindowHeightState2,
TransTextPixel);
return EVENT_DEPTH_CUE;
}
else if (LclFullTransMode &&
Event.xbutton.window == SaveMatrixWndw) {
return EVENT_SAVE_MATRIX;
}
else if (LclFullTransMode &&
Event.xbutton.window == SaveGIFWndw) {
return EVENT_SAVE_GIF;
}
else if (LclFullTransMode &&
Event.xbutton.window == SavePSWndw) {
return EVENT_SAVE_PS;
}
else if (Event.xbutton.window == ResetMatrixWndw) {
return EVENT_RESET_MATRIX;
}
else if (Event.xbutton.window == QuitWndw) {
if (!PopTransWndwAlways)
XUnmapWindow(XDisplay, TransformWndw);
GGGraphicFlush();
return EVENT_QUIT;
}
break;
case MotionNotify:
/* We may get events of movement in Y which are ignored. */
if (Event.xbutton.x - LastX == 0) break;
*ChangeFactor = ((RealType) (Event.xbutton.x - LastX)) /
SubWindowWidthState2;
LastX = Event.xbutton.x;
if (Event.xbutton.window == PersOrthoZWndw) {
return EVENT_PERS_ORTHO_Z;
}
else if (Event.xbutton.window == RotateXWndw) {
return EVENT_ROTATE_X;
}
else if (Event.xbutton.window == RotateYWndw) {
return EVENT_ROTATE_Y;
}
else if (Event.xbutton.window == RotateZWndw) {
return EVENT_ROTATE_Z;
}
else if (Event.xbutton.window == TranslateXWndw) {
return EVENT_TRANSLATE_X;
}
else if (Event.xbutton.window == TranslateYWndw) {
return EVENT_TRANSLATE_Y;
}
else if (Event.xbutton.window == TranslateZWndw) {
return EVENT_TRANSLATE_Z;
}
else if (Event.xbutton.window == ScaleWndw) {
return EVENT_SCALE;
}
break;
default:
fprintf(stderr, "undefined event type %d.\n", Event.type);
}
}
}
/******************************************************************************
* Draw text centered at the given position. *
******************************************************************************/
static void DrawText(Window Win, char *Str, int PosX, int PosY,
unsigned long Color)
{
int Len = strlen(Str),
Width = XTextWidth(XLoadedFont, Str, Len);
XGCValues values;
values.foreground = Color;
XChangeGC(XDisplay, XTransGraphContext, GCForeground, &values);
XDrawString(XDisplay, Win, XTransGraphContext, PosX - Width / 2,
PosY + XFontYOffsetToCenter, Str, Len);
}